package effects;

import loadsave.Memento;
import loadsave.loadsaveobject.Iterator;
import loadsave.loadsaveobject.LoadSaveObject;
import loadsave.loadsaveobject.LoadSaveObjectComposite;
import stat.EntityStatList;
import stat.NonEntityStatList;
import stat.StatList;
import stat.StatType;
import visitors.EffectsVisitor;

/**
 * The InstantDeathEffect class is meant to encapsulate
 * an effect that removes all health from an entity.
 * This class is necessary as a target for double
 * dispatch for the Visitor class.
 * 
 * InstantDeathEffect is simply used to override the
 * accept() method to appropriate the correct effect
 * method in the Visitor.
 * 
 * @author DangMH
 *
 */
public class InstantDeathEffect extends Effect {
	StatList deathStats;
	
	/**
	 * Empty Constructor
	 */
	public InstantDeathEffect() {
		deathStats = new NonEntityStatList();
	}
	
	/**
	 * Parameterized Constructor
	 * @param modelName
	 * Name of the modal image
	 * @param statList
	 * Stats for lives lost influence
	 */
	public InstantDeathEffect( String modelName, StatList statList ) {
		super( modelName );
		this.deathStats = statList;
	}
	
	/**
	 * Visitor interface
	 */
	public void accept( EffectsVisitor ev ) {
		ev.visitInstantDeathEffect( this );
	}

	/**
	 * Computes the delta lives, assumes addStats
	 */
	public StatList computeStats() {
		StatList ret = new NonEntityStatList();
		
		ret.addStat( StatType.LIVES, computeLives() );
		
		return ret;
	}
	
	/**
	 * private method to derive the delta lives
	 */
	private int computeLives() {
		int ret = 0;
		
		for( StatType st : getRelevantStats() ) {
			ret += deathStats.getStat( st );
		}
		
		return ret;
	}

	@Override
	public Memento getMemento() {
		return new Memento() {

			@Override
			public LoadSaveObject getState() {
				LoadSaveObject lso = InstantDeathEffect.super.getMemento().getState();
				LoadSaveObjectComposite toReturn = new LoadSaveObjectComposite("", "InstantDeathEffect");
				Iterator<LoadSaveObject> i = lso.getIterator();
				for (i.init(); i.hasNext(); i.next()) {
					toReturn.add(i.getCurrKey().getValue(), i.getCurrVal());
				}
				lso = deathStats.getMemento().getState();
				lso.setName("deathStats");
				toReturn.add(lso.getName(), lso);
				return toReturn;
			}

			@Override
			public void restoreState(LoadSaveObject lso) {
				InstantDeathEffect.super.getMemento().restoreState(lso);
				deathStats = new EntityStatList();
				deathStats.getMemento().restoreState(lso.get("deathStats"));
			}
			
		};
	}

	/**
	 * public mutator for stats
	 */
	public void setStats(StatList statList) {
		deathStats = statList;
		
	}

	@Override
	public InstantDeathEffect clone() {
		StatList dStats = new EntityStatList();
		dStats.addStats(this.deathStats);
		return new InstantDeathEffect(getName(), dStats);
	}
}
